package com.itheima.reggie.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.Pojo.Category;
import com.itheima.reggie.Pojo.Setmeal;
import com.itheima.reggie.Pojo.SetmealDish;
import com.itheima.reggie.Service.CategoryService;
import com.itheima.reggie.Service.SetmealDishService;
import com.itheima.reggie.Service.SetmealService;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.SetmealDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;


import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 套餐管理
 */
@RestController
@RequestMapping("/setmeal")
public class SetmealController {
    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 新增套餐
     * @param setmealDto
     * @return
     */
    @CacheEvict(value = "Setmealcache",key="#setmealDto.categoryId")
    @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto){
        setmealService.save_dish(setmealDto);
        return R.success("插入成功");
    }

    /**
     * 套餐分页查询，因为包含分类名称，所以只能用SetmealDto类型的对象
     * 因为Setmeal没有该属性，所以查询出来的数据缺少分类名称这个属性，所以需要创建一个SetmealDto对象
     * 将查询出来的Setmeal对象拷贝到SetmealDto对象中，因为数据不全，所以拷贝的时候忽略数据，只拷贝分页
     * 的信息、框架，然后将数据改造后(给分类名称赋值)，再单独给SetmealDto对象的数据属性(records)赋值
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
//      分页构造器
        Page<Setmeal> setmealPage = new Page<>(page,pageSize);
        Page<SetmealDto> page1 = new Page<>();
//      条件构造器
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(name!=null,Setmeal::getName,name);
//      分页查询
        setmealService.page(setmealPage,queryWrapper);
//      拷贝，从setmealPage拷贝分页数据到page1，忽略掉records属性
        BeanUtils.copyProperties(setmealPage,page1,"records");
//      获取setmealPage中records属性的值
        List<Setmeal> records = setmealPage.getRecords();
//      遍历records
        List<SetmealDto> list = records.stream().map((item) -> {
//          创建SetmealDto对象
            SetmealDto setmealDto = new SetmealDto();
//          获取套餐分类的id
            Long categoryId = item.getCategoryId();
//          通过分类id获取分类对象
            Category category = categoryService.getById(categoryId);
            if (category != null) {
//              通过分类对象获取该分类的名字
                String categoryName = category.getName();
//              给setmealDto的categoryName属性赋值
                setmealDto.setCategoryName(categoryName);
            }
//          拷贝其他的数据到setmealDto中
            BeanUtils.copyProperties(item, setmealDto);
            return setmealDto;

        }).collect(Collectors.toList());
//      给page1的records属性赋值
        page1.setRecords(list);
        return R.success(page1);

    }

    /**
     * 回显套餐数据
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<SetmealDto> selectid(@PathVariable Long id){
//      根据id获取套餐数据
        Setmeal setmeal = setmealService.getById(id);
//      new一个SetmealDto对象
        SetmealDto setmealDto = new SetmealDto();
//      拷贝数据
        BeanUtils.copyProperties(setmeal,setmealDto);

        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(id!=null,SetmealDish::getDishId,id);
        List<SetmealDish> list = setmealDishService.list(queryWrapper);

        setmealDto.setSetmealDishes(list);
        return R.success(setmealDto);
    }

    /**
     * 修改套餐
     * @param setmealDto
     * @return
     */
    @CacheEvict(value = "Setmealcache",key="#setmealDto.categoryId")
    @PutMapping
    public R<String> update(@RequestBody SetmealDto setmealDto){
        setmealService.updateById(setmealDto);
        List<SetmealDish> list = setmealDto.getSetmealDishes();
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(setmealDto.getId()!=null,SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishService.remove(queryWrapper);
        for (SetmealDish dish : list) {
            dish.setSetmealId(setmealDto.getId());
        }
        setmealDishService.saveBatch(list);
        return R.success("修改成功");
    }

    /**
     * 更改套餐状态，起售或停售
     * @param id
     * @param ids
     * @return
     */
    @CacheEvict(value = "Setmealcache",allEntries = true)
    @PostMapping("/status/{id}")
    public R<String> stop(@PathVariable Integer id, Long[] ids){
//      创建Setmeal对象
            Setmeal setmeal = new Setmeal();
//      给id跟status赋值
            setmeal.setStatus(id);
        for (Long idss : ids) {
            setmeal.setId(idss);
//      修改数据库中该对象的状态
            setmealService.updateById(setmeal);
        }

        return R.success("状态更改成功");
    }

    /**
     * 删除套餐以及相关的套餐菜品关联表
     * @param ids
     * @return
     */
//  allEntries:删除整个缓存空间的数据，即同一个缓存空间下所有缓存数据，默认为false
//  value:缓存空间
    @CacheEvict(value = "Setmealcache",allEntries = true)
    @DeleteMapping
    public R<String> dcelete(Long[] ids){
        for (Long id : ids) {
//          删除套餐
            setmealService.removeById(id);
//          删除套餐菜品关联表
            LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(id!=null,SetmealDish::getSetmealId,id);
            setmealDishService.remove(queryWrapper);

        }

        return R.success("删除成功");

    }

    /**
     * 根据套餐分类查询相应的套餐
     * @param setmeal
     * @return
     */
//  返回的对象(R)需要实现序列化接口,这样才能够被缓存接收为key
//  value：缓存空间  key：缓存的key
    @Cacheable(value = "Setmealcache",key = "#setmeal.categoryId")
    @GetMapping("/list")
    public R<List<Setmeal>> select(Setmeal setmeal){

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
//      根据分类id查询
        queryWrapper.eq(setmeal.getCategoryId()!=null,Setmeal::getCategoryId,setmeal.getCategoryId());
        List<Setmeal> list = setmealService.list(queryWrapper);
        return R.success(list);
    }

}
